﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Presentation;
using System.IO;
using System.Linq;
using D = DocumentFormat.OpenXml.Drawing;
using P = DocumentFormat.OpenXml.Presentation;

namespace demo_ver2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public IList<string> ListTitle;
        private PptxHelper pptxHelper;
        int currentPPItem = -1;
        int numofword = 0;
        public MainWindow()
        {
            this.InitializeComponent();
            this.DataContext = this;
            // Insert code required on object creation below this point.

        }


        private Utils.RelayCommand _cmdCloseCommand;
        /// <summary>
        /// Returns a command that closes a TabItem.
        /// </summary>
        public ICommand CloseCommand
        {
            get
            {
                if (_cmdCloseCommand == null)
                {
                    _cmdCloseCommand = new Utils.RelayCommand(
                        param => this.CloseTab_Execute(param),
                        param => this.CloseTab_CanExecute(param)
                        );
                }
                return _cmdCloseCommand;
            }
        }

        /// <summary>
        /// Called when the command is to be executed.
        /// </summary>
        /// <param name="parm">
        /// The TabItem in which the Close-button was clicked.
        /// </param>
        private void CloseTab_Execute(object parm)
        {
            TabItem ti = parm as TabItem;
            if (ti != null)
            {
                int i = ItemsControl.ItemsControlFromItemContainer(ti).ItemContainerGenerator.IndexFromContainer(ti);
                string name = "wfh" + i;
                try
                {
                    System.Windows.Forms.Integration.WindowsFormsHost wfh = this.FindChild<System.Windows.Forms.Integration.WindowsFormsHost>(Application.Current.MainWindow, name);
                    //if((wfh.Child as OfficeControl)
                    (wfh.Child as OfficeControl).close();
                }
                catch { };

                tc.Items.Remove(parm);
            }
        }

        /// <summary>
        /// Called when the availability of the Close command needs to be determined.
        /// </summary>
        /// <param name="parm">
        /// The TabItem for which to determine the availability of the Close-command.
        /// </param>
        private bool CloseTab_CanExecute(object parm)
        {
            //For the sample, the closing of TabItems will only be
            //unavailable for disabled TabItems and the very first TabItem.
            TabItem ti = parm as TabItem;
            if (ti != null && ti != tc.Items[0])
                //We have a valid reference to a TabItem, so return 
                //true if the TabItem is enabled.
                return ti.IsEnabled;

            //If no reference to a TabItem could be obtained, the command 
            //cannot be executed
            return false;
        }



        //public static int RetrieveNumberOfSlides(PresentationPart presentationPart)
        //{
        //    int slidesCount = 0;


        //    if (presentationPart != null)
        //    {
        //        slidesCount = presentationPart.SlideParts.Count();
        //    }

        //    return slidesCount;
        //}

        public static string[] GetAllTextInSlide(string presentationFile, int slideIndex)
        {
            // Open the presentation as read-only.
            using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
            {
                // Pass the presentation and the slide index
                // to the next GetAllTextInSlide method, and
                // then return the array of strings it returns. 
                return GetAllTextInSlide(presentationDocument, slideIndex);
            }
        }

        public static string[] GetAllTextInSlide(PresentationDocument presentationDocument, int slideIndex)
        {
            // Verify that the presentation document exists.
            if (presentationDocument == null)
            {
                throw new ArgumentNullException("presentationDocument");
            }

            // Verify that the slide index is not out of range.
            if (slideIndex < 0)
            {
                throw new ArgumentOutOfRangeException("slideIndex");
            }

            // Get the presentation part of the presentation document.
            PresentationPart presentationPart = presentationDocument.PresentationPart;

            // Verify that the presentation part and presentation exist.
            if (presentationPart != null && presentationPart.Presentation != null)
            {
                // Get the Presentation object from the presentation part.
                Presentation presentation = presentationPart.Presentation;

                // Verify that the slide ID list exists.
                if (presentation.SlideIdList != null)
                {
                    // Get the collection of slide IDs from the slide ID list.
                    var slideIds = presentation.SlideIdList.ChildElements;

                    // If the slide ID is in range...
                    if (slideIndex < slideIds.Count)
                    {
                        // Get the relationship ID of the slide.
                        string slidePartRelationshipId = (slideIds[slideIndex] as SlideId).RelationshipId;

                        // Get the specified slide part from the relationship ID.
                        SlidePart slidePart = (SlidePart)presentationPart.GetPartById(slidePartRelationshipId);

                        // Pass the slide part to the next method, and
                        // then return the array of strings that method
                        // returns to the previous method.
                        return GetAllTextInSlide(slidePart);
                    }
                }
            }
            // Else, return null.
            return null;
        }


        public static string[] GetAllTextInSlide(SlidePart slidePart)
        {
            // Verify that the slide part exists.
            if (slidePart == null)
            {
                throw new ArgumentNullException("slidePart");
            }

            // Create a new linked list of strings.
            LinkedList<string> texts = new LinkedList<string>();

            // If the slide exists...
            if (slidePart.Slide != null)
            {

                getSlideContent(slidePart.Slide);
                // Iterate through all the paragraphs in the slide.
                foreach (var paragraph in slidePart.Slide.Descendants<DocumentFormat.OpenXml.Drawing.Paragraph>())
                {
                    // Create a new string builder.                    
                    StringBuilder paragraphText = new StringBuilder();

                    // Iterate through the lines of the paragraph.
                    foreach (var text in paragraph.Descendants<DocumentFormat.OpenXml.Drawing.Text>())
                    {
                        // Append each line to the previous lines.
                        paragraphText.Append(text.Text);
                    }

                    if (paragraphText.Length > 0)
                    {
                        // Add each paragraph to the linked list.
                        texts.AddLast(paragraphText.ToString());
                    }
                }
            }

            if (texts.Count > 0)
            {
                // Return an array of strings.
                return texts.ToArray();
            }
            else
            {
                return null;
            }
        }

        public T FindChild<T>(DependencyObject parent, string childName)
  where T : DependencyObject
        {
            // Confirm parent and childName are valid. 
            if (parent == null) return null;

            T foundChild = null;

            int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < childrenCount; i++)
            {
                var child = VisualTreeHelper.GetChild(parent, i);
                // If the child is not of the request child type child
                T childType = child as T;
                if (childType == null)
                {
                    // recursively drill down the tree
                    foundChild = FindChild<T>(child, childName);

                    // If the child is found, break so we do not overwrite the found child. 
                    if (foundChild != null) break;
                }
                else if (!string.IsNullOrEmpty(childName))
                {
                    var frameworkElement = child as FrameworkElement;
                    // If the child's name is set for search
                    if (frameworkElement != null && frameworkElement.Name == childName)
                    {
                        // if the child's name is of the request name
                        foundChild = (T)child;
                        break;
                    }
                }
                else
                {
                    // child element found.
                    foundChild = (T)child;
                    break;
                }
            }

            return foundChild;
        }


        string filename = "";
        private void menu_Import_Click(object sender, RoutedEventArgs e)
        {

            System.Windows.Forms.OpenFileDialog dlg = new System.Windows.Forms.OpenFileDialog();
            dlg.Filter = "File Powerpoint (*.pptx)|*.pptx";
            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                filename = dlg.FileName;

            }
            pptxHelper = new PptxHelper(filename);
            //PresentationDocument doc =
            //   PresentationDocument.Open(filename, false);
            //// Get the presentation part of the document.
            //PresentationPart presentationPart = doc.PresentationPart;
            this.ListTitle = pptxHelper.GetSlideTitles();
            //PresentationDocument presentFIle = PresentationDocument.Open(filename, true);
            //string creator = presentFIle.PackageProperties.Creator;
            int numofslide = pptxHelper.RetrieveNumberOfSlides();
            ListBox listbox = this.FindChild<ListBox>(Application.Current.MainWindow, "SidesList");

            listbox.Items.Clear();
            for (int i = 0; i < numofslide; i++)
            {
                string item = (i + 1) + ListTitle[i];
                listbox.Items.Add(item);
            }
            listbox.SelectedIndex = 0;
            //pptxHelper.MyGetAllTextInSlide(0).BindTextToControl(m_richTextEditor.RichTextBox);
            // AddContentToRichTextBox(filename,0);
        }

        private void AddContentToRichTextBox(string filename, int slideIndex)
        {
            PresentationDocument doc =
                PresentationDocument.Open(filename, false);
            string[] texts = GetAllTextInSlide(doc, slideIndex);
            for (int i = 0; i < texts.Count(); i++)
            {

                // m_richTextEditor.RichTextBox.AppendText(texts[i]);
                //m_richTextEditor.RichTextBox.AppendText("\n");

            }
        }

        private FlowDocument getSlideContent(int slideIndex)
        {
            FlowDocument myFlowDoc = new FlowDocument();
            return myFlowDoc;
        }

        private static FlowDocument getSlideContent(Slide slide)
        {
            FlowDocument myFlowDoc = new FlowDocument();
            foreach (var paragraph in slide.Descendants<DocumentFormat.OpenXml.Drawing.Paragraph>())
            {

                // Create a new string builder.                    
                StringBuilder paragraphText = new StringBuilder();
                D.ParagraphProperties pro = paragraph.ParagraphProperties;
                if (pro != null)
                {
                    string xml = pro.InnerXml;
                }
                // Iterate through the lines of the paragraph.
                foreach (var text in paragraph.Descendants<DocumentFormat.OpenXml.Drawing.Text>())
                {
                    // Append each line to the previous lines.
                    paragraphText.Append(text.Text);

                }

                if (paragraphText.Length > 0)
                {
                    // Add each paragraph to the linked list.
                    // texts.AddLast(paragraphText.ToString());
                }
            }
            return myFlowDoc;
        }

        //next slide
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            ListBox listbox = this.FindChild<ListBox>(Application.Current.MainWindow, "SidesList");
            listbox.SelectedIndex++;
            // m_richTextEditor.RichTextBox.Document.Blocks.Clear();
            //   this.pptxHelper.MyGetAllTextInSlide(listbox.SelectedIndex).BindTextToControl(m_richTextEditor.RichTextBox);


            PresentationDocument doc = PresentationDocument.Open(filename, false);
            //SlideId slideid = 
            Presentation presentation = doc.PresentationPart.Presentation;
            var slidelist = presentation.SlideIdList.ChildElements;

            string slideRelationShip = (slidelist[listbox.SelectedIndex] as SlideId).RelationshipId;
            SlidePart slide_part = doc.PresentationPart.GetPartById(slideRelationShip) as SlidePart;
            if (slide_part == null || slide_part.Slide == null)
            {
                return;
            }
            Slide slide = slide_part.Slide;
            foreach (var pic in slide.Descendants<Picture>())
            {
                // how can one obtain the pic format and image data?
                // First, get relationship id of image
                string rId = pic.BlipFill.Blip.Embed.Value;

                ImagePart imagePart = (ImagePart)slide.SlidePart.GetPartById(rId);

                //MessageBox.Show(imagePart.Uri.OriginalString);
                //BitmapImage bitmap = new BitmapImage(imagePart.Uri);

                Paragraph para = new Paragraph();
                // Add an image
                para = new Paragraph();
                //MessageBox.Show(imagePart.Uri.LocalPath);
                //Uri uri = new Uri("c:/image.jpg");
                System.Drawing.Image imagestr = System.Drawing.Image.FromStream(imagePart.GetStream());

                MemoryStream ms = new MemoryStream();
                imagestr.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                System.Windows.Media.Imaging.BitmapImage bImg = new System.Windows.Media.Imaging.BitmapImage();
                bImg.BeginInit();
                bImg.StreamSource = new MemoryStream(ms.ToArray());
                bImg.EndInit();

                System.Windows.Controls.Image image = new System.Windows.Controls.Image();
                image.Source = bImg;
                para.Inlines.Add(image);

            }
        }

        private void menu_Open_Click(object sender, RoutedEventArgs e)
        {

            System.Windows.Forms.OpenFileDialog openFileDialog1 = new System.Windows.Forms.OpenFileDialog();

            string filNm;
            openFileDialog1.Multiselect = false;
            //openFileDialog1.Filter = "MS-Word Files (*.doc,*.dot,*.dotx) | *.doc;*.dot;*.dotx";
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                filNm = openFileDialog1.FileName;
                OfficeControl officeControl = new OfficeControl();
                string mode = "";
                mode = getModeOfFile(filNm);
                if (mode.Length > 0)
                {
                    //officeControl.close();
                    if (currentPPItem >= 0)
                    {
                        System.Windows.Forms.Integration.WindowsFormsHost wfh = (tc.Items.GetItemAt(currentPPItem) as TabItem).Content as System.Windows.Forms.Integration.WindowsFormsHost;
                        (wfh.Child as OfficeControl).close();
                    }
                    officeControl.open(filNm, mode);
                    TabItem item = new TabItem();
                    item.Header = filNm;
                    System.Windows.Forms.Integration.WindowsFormsHost wfhcontroltemp = new System.Windows.Forms.Integration.WindowsFormsHost();
                    wfhcontroltemp.Name = "wfh" + tc.Items.Count;
                    wfhcontroltemp.Child = officeControl;
                    item.Content = wfhcontroltemp;

                    if (EqualsExtend(filNm, "pptx"))
                    {
                        item.MouseLeftButtonUp += new MouseButtonEventHandler(item_MouseLeftButtonUp);

                        currentPPItem = tc.Items.Count;
                    }

                   
                   
                    this.tc.Items.Add(item);
                    this.tc.SelectedIndex = tc.Items.Count - 1;
                    //  item.Content = new 
                    //this.tc.Items
                    //  this.WindowsFormHost2.Child = officeControl;
                }
                else
                {
                    if (EqualsExtend(filNm, "pdf"))
                    {
                        TabItem item = new TabItem();
                        item.Header = filNm;
                        System.Windows.Forms.Integration.WindowsFormsHost wfhcontroltemp = new System.Windows.Forms.Integration.WindowsFormsHost();
                        wfhcontroltemp.Name = "wfh" + tc.Items.Count;
                        wfhcontroltemp.Child = new MyPdfViewer(filNm);
                        item.Content = wfhcontroltemp;
                        this.tc.Items.Add(item);
                        this.tc.SelectedIndex = tc.Items.Count - 1;
                    }
                }
            }

        }

        private bool EqualsExtend(string filename, string _extend)
        {
            bool rs = false;
            int stringLeght = filename.Length;
            for (int i = stringLeght - 1; i > 0; i--)
            {
                if ((int)filename[i] == 46)
                {
                    int extendLeght = stringLeght - i - 1;
                    string extend = filename.Substring(i + 1, extendLeght);
                    if (extend.Equals(_extend))
                        rs = true;
                    return rs;
                }
            }
            return rs;
        }
        private string getModeOfFile(string filename)
        {

            string rs = "";
            int stringLeght = filename.Length;
            for (int i = stringLeght - 1; i > 0; i--)
            {
                if ((int)filename[i] == 46)
                {
                    int extendLeght = stringLeght - i - 1;
                    string extend = filename.Substring(i + 1, extendLeght);
                    if (extend.Equals("docx"))
                        rs = "Word.Application";
                    if (extend.Equals("pptx"))
                        rs = "PowerPoint.Application";
                    if (extend.Equals("xlsx"))
                        rs = "Excel.Application";
                    return rs;
                }
            }
            return rs;
        }


        private void Tabitem_GotFocus(object sender, RoutedEventArgs e)
        {
        }

        private void Tabitem_LostFocus(object sender, RoutedEventArgs e)
        {
            TabItem ti = sender as TabItem;
            int i = ItemsControl.ItemsControlFromItemContainer(ti).ItemContainerGenerator.IndexFromContainer(ti);
            string name = "wfh" + i;
            System.Windows.Forms.Integration.WindowsFormsHost wfh = ti.Content as System.Windows.Forms.Integration.WindowsFormsHost;
            //System.Windows.Forms.Integration.WindowsFormsHost wfh = this.FindChild<System.Windows.Forms.Integration.WindowsFormsHost>(Application.Current.MainWindow, name);
            (wfh.Child as OfficeControl).close();
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            //int tabcount = tc.Items.Count;
            //for (int i = 0; i < tabcount; i++)
            //{
            //    try
            //    {
            //        string name = "wfh" + i;
            //        System.Windows.Forms.Integration.WindowsFormsHost wfh = this.FindChild<System.Windows.Forms.Integration.WindowsFormsHost>(Application.Current.MainWindow, name);
            //        (wfh.Child as PPointControl).close();
            //    }
            //    catch { }
            //}
            if(currentPPItem > 0)
            {
            System.Windows.Forms.Integration.WindowsFormsHost wfh = (tc.Items.GetItemAt(currentPPItem) as TabItem).Content as System.Windows.Forms.Integration.WindowsFormsHost;
            (wfh.Child as PPointControl).close();
            }
        }

        private void Image_ImageFailed(object sender, ExceptionRoutedEventArgs e)
        {

        }


        private void Button_Click2(object sender, RoutedEventArgs e)
        {
            Window1 win = new Window1();
            win.WindowState = WindowState.Maximized;
            win.ShowDialog();
        }


        private void TabWorditem_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            TabItem ti = sender as TabItem;
           // int i = ItemsControl.ItemsControlFromItemContainer(ti).ItemContainerGenerator.IndexFromContainer(ti);
            
                System.Windows.Forms.Integration.WindowsFormsHost wfh = ti.Content as System.Windows.Forms.Integration.WindowsFormsHost;
            //    (wfh.Child as WordControl).reactive();
           
        }

        private void item_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            //TabItem ti = sender as TabItem;
            //int i = ItemsControl.ItemsControlFromItemContainer(ti).ItemContainerGenerator.IndexFromContainer(ti);
            //if (currentPPItem >= 0 && currentPPItem != i)
            //{
            //    //System.Windows.Forms.Integration.WindowsFormsHost wfh = (tc.Items.GetItemAt(currentPPItem) as TabItem).Content as System.Windows.Forms.Integration.WindowsFormsHost;
            //    //(wfh.Child as OfficeControl).close();

            //    //wfh = ti.Content as System.Windows.Forms.Integration.WindowsFormsHost;
            //    //(wfh.Child as OfficeControl).open(ti.Header.ToString(), "PowerPoint.Application");
            //    //currentPPItem = i;
            //}

            TabItem ti = sender as TabItem;           

            System.Windows.Forms.Integration.WindowsFormsHost wfh = ti.Content as System.Windows.Forms.Integration.WindowsFormsHost;
            (wfh.Child as PPointControl).Reactive();
        }

        private void export_Import_Click(object sender, RoutedEventArgs e)
        {
             System.Windows.Forms.OpenFileDialog openFileDialog1 = new System.Windows.Forms.OpenFileDialog();

            string filNm;
            openFileDialog1.Multiselect = false;
            //openFileDialog1.Filter = "MS-Word Files (*.doc,*.dot,*.dotx) | *.doc;*.dot;*.dotx";
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                
                filNm = openFileDialog1.FileName;
                string safename = openFileDialog1.SafeFileName;
                //if (EqualsExtend(filNm, "docx"))
                if (EqualsExtend(filNm, "pptx"))
                {
                    
                    if (currentPPItem >= 0)
                    {
                        tc.SelectedIndex = currentPPItem;
                        string name = "wfh" + currentPPItem;
                        System.Windows.Forms.Integration.WindowsFormsHost wfh1 = (tc.Items.GetItemAt(currentPPItem) as TabItem).Content as System.Windows.Forms.Integration.WindowsFormsHost;
                        (wfh1.Child as PPointControl).close();
                        wfh1.Child = new PPointControl(filNm, safename);
                        //(wfh1.Child as PPointControl).open();
                       // MessageBox.Show("wait");
                        System.Threading.Thread.Sleep(1000);
                        (wfh1.Child as PPointControl).open();
                    }
                    else
                    {
                        TabItem item = new TabItem();
                        item.Header = filNm;
                        System.Windows.Forms.Integration.WindowsFormsHost wfhcontroltemp = new System.Windows.Forms.Integration.WindowsFormsHost();
                        wfhcontroltemp.Name = "wfh" + tc.Items.Count;
                        
                      
                       // wfhcontroltemp.Child = new WordControl(filNm, numofword);
                        wfhcontroltemp.Child = new PPointControl(filNm, safename);
                        item.Content = wfhcontroltemp;

                       // item.MouseLeftButtonUp += new MouseButtonEventHandler(item_MouseLeftButtonUp);
                        
                        this.tc.Items.Add(item);
                        int i = tc.Items.Count;
                        this.tc.SelectedIndex = i - 1;
                        System.Windows.Forms.Integration.WindowsFormsHost wfh = (tc.Items.GetItemAt(i - 1) as TabItem).Content as System.Windows.Forms.Integration.WindowsFormsHost;
                        (wfh.Child as PPointControl).open();
                        this.currentPPItem = i - 1;
                    }
                    //(wfh.Child as WordControl).open();
                }
                if (EqualsExtend(filNm, "docx"))
                {

                    TabItem item = new TabItem();
                    item.Header = filNm;
                    System.Windows.Forms.Integration.WindowsFormsHost wfhcontroltemp = new System.Windows.Forms.Integration.WindowsFormsHost();
                    wfhcontroltemp.Name = "wfh" + tc.Items.Count;

                    numofword++;
                    wfhcontroltemp.Child = new WordControl(filNm, numofword);
                    //wfhcontroltemp.Child = new PPointControl(filNm, safename);
                    item.Content = wfhcontroltemp;

                    item.MouseLeftButtonUp += new MouseButtonEventHandler(TabWorditem_MouseLeftButtonUp);

                    this.tc.Items.Add(item);
                    int i = tc.Items.Count;
                    this.tc.SelectedIndex = i - 1;
                    System.Windows.Forms.Integration.WindowsFormsHost wfh = (tc.Items.GetItemAt(i - 1) as TabItem).Content as System.Windows.Forms.Integration.WindowsFormsHost;

                    (wfh.Child as WordControl).open();
                }
                if (EqualsExtend(filNm, "pdf"))
                {
                    TabItem item = new TabItem();
                    item.Header = safename;
                    System.Windows.Forms.Integration.WindowsFormsHost wfhcontroltemp = new System.Windows.Forms.Integration.WindowsFormsHost();
                    wfhcontroltemp.Name = "wfh" + tc.Items.Count;
                    wfhcontroltemp.Child = new MyPdfViewer(filNm);
                    item.Content = wfhcontroltemp;
                    tc.Items.Add(item);
                    int i = tc.Items.Count;
                    this.tc.SelectedIndex = i - 1;
                }
                
            }
        }

        private void dragCanvas_Loaded(object sender, RoutedEventArgs e)
        {
            for (int i = 0; i < 1000; i++)
            {
                Polygon pol = new Polygon();
                pol.Fill=new SolidColorBrush(Color.FromRgb(1,0,1));
                pol.Points.Add(new Point(0.0, 0.0));
                pol.Points.Add(new Point(0.0, 100.0));
                pol.Points.Add(new Point(100.0, 50.0));
                this.dragCanvas.Children.Add(pol);
            }
        }

    }
}